﻿



using Aspose.Cells;
using System.Windows.Forms;

namespace CheccCoverplateCulvertAssemble.Conmmon;

internal class ItemTypeHelpers
{
    public static IECClass[] GetItemTypeAllECClass(ItemTypeLibrary lib)
    {
        List<IECClass> eCClasses = new();
        if (lib == null)
        {
            return eCClasses.ToArray();
        }
        DgnECManager manager = DgnECManager.Manager;
        List<string> list = manager.DiscoverSchemasForModel(GeneralHelpers.ActiveDgnModel, ReferencedModelScopeOption.All, false).ToList();
        IECClass[] classes = lib.ECSchema.GetClasses();
        foreach (IECClass eCClass in classes)
        {
            if (!eCClass.IsStruct() && eCClass is not IECRelationshipClass)
            {
                eCClasses.Add(eCClass);
            }
        }
        GetECClassListBySchemaName(lib.ECSchema.FullName, ref eCClasses);
        return eCClasses.ToArray();
    }
    public static List<IECProperty> GetItemTypeECProperty(IECClass ecClass)
    {
        List<IECProperty> eCPropertyList = new();
        if (ecClass == null)
        {
            return eCPropertyList;
        }
        foreach (IECProperty item in ecClass)
        {
            eCPropertyList.Add(item);
        }
        return eCPropertyList;
    }
    private static void GetECClassListBySchemaName(string fullSchemaName, ref List<IECClass> eCClassList)
    {
        ECObjects.ParseFullSchemaName(out string schemaName, out int versionMajor, out int versionMinor, fullSchemaName);
        FindInstancesScope findInstancesScope = FindInstancesScope.CreateScope(GeneralHelpers.ActiveDgnModel, new FindInstancesScopeOption(DgnECHostType.All));
        string text = "DgnComponent___" + schemaName;
        IECSchema eCSchemas = DgnECManager.Manager.LocateSchemaInScope(findInstancesScope, text, versionMajor, versionMinor, SchemaMatchType.LatestCompatible);
        if (eCSchemas == null)
        {
            return;
        }
        IECClass[] eCClasses = eCSchemas.GetClasses();
        foreach (IECClass eCClass in eCClasses)
        {
            if (!eCClass.IsStruct() && (eCClass is not IECRelationshipClass))
            {
                eCClassList.Add(eCClass);
            }
        }
    }
    public static ItemTypeLibrary NewTypeLibrary(string name)
    {
        ItemTypeLibrary itemTypeLibrary = ItemTypeLibrary.FindByName(name, GeneralHelpers.ActiveDgnFile);
        if (itemTypeLibrary != null)
        {
            return itemTypeLibrary;
        }
        itemTypeLibrary = ItemTypeLibrary.Create(name, GeneralHelpers.ActiveDgnFile);
        itemTypeLibrary.Write();
        return itemTypeLibrary;
    }
    public static ItemTypeLibrary GetTypeLibraryFromName(string libraryName)
    {
        List<ItemTypeLibrary> allTypeLibrary = GetAllTypeLibrary();
        foreach (ItemTypeLibrary item in allTypeLibrary)
        {
            if (item.Name == libraryName)
            {
                return item;
            }
        }
        return null;
    }
    public static List<ItemTypeLibrary> GetAllTypeLibrary()
    {
        DgnFile activeDgnFile = GeneralHelpers.ActiveDgnFile;
        return ItemTypeLibrary.PopulateListFromFile(activeDgnFile).ToList();
    }
    public static ItemType NewItemType(ItemTypeLibrary lib, string itemTypeName)
    {
        ItemType itemType = lib.GetItemTypeByName(itemTypeName);
        if (itemType != null)
        {
            return itemType;
        }
        itemType = lib.AddItemType(itemTypeName);
        lib.Write();
        return itemType;
    }
    public static ItemType GetItemTypeFromName(ItemTypeLibrary lib, string itemTypeName)
    {
        return lib.GetItemTypeByName(itemTypeName);
    }
    public static CustomPropertyType NewPropertyDefinition(ItemTypeLibrary lib, string className)
    {
        return lib.AddCustomType(className);
    }
    public static CustomProperty NewPropertyType(CustomPropertyContainer itemType, string propertyTypeName, CustomProperty.TypeKind type, bool isArry, bool isHidden)
    {
        CustomProperty customProperty = itemType.GetPropertyByName(propertyTypeName);
        if (customProperty != null)
        {
            return customProperty;
        }
        customProperty = itemType.AddProperty(propertyTypeName);
        customProperty.Type = type;
        customProperty.IsArray = isArry;
        customProperty.IsHiddenProperty = isHidden;
        itemType.Library.Write();
        return customProperty;
    }
    public static CustomProperty GetPropertyTypeFromName(CustomPropertyContainer itemType, string propertyTypeName)
    {
        return itemType.GetPropertyByName(propertyTypeName);
    }
    public static List<Element> GetElementFormItemType(ItemType type, bool includeAttach)
    {
        List<Element> elements = new();
        if (type == null)
        {
            return elements;
        }
        DgnECManager manager = DgnECManager.Manager;
        ECQuery eCQuery = QueryHelper.CreateQuery(type.ECClass.Schema, new string[] { type.InternalName });
        eCQuery.SelectClause.SelectAllProperties = true;
        FindInstancesScope findInstancesScope = FindInstancesScope.CreateScope(GeneralHelpers.ActiveDgnFile, new FindInstancesScopeOption(DgnECHostType.Element, includeAttach));
        if (findInstancesScope == null)
        {
            return elements;
        }
        using DgnECInstanceCollection dgnECInstanceCollection = manager.FindInstances(findInstancesScope, eCQuery);

        if (dgnECInstanceCollection != null)
        {
            foreach (IDgnECInstance item in dgnECInstanceCollection)
            {
                elements.Add(item.Element);
            }
        }
        return elements;
    }
    public static List<IDgnECInstance> GetECInstanceListFormItemType(ItemType type, bool includeAttach)
    {
        List<IDgnECInstance> dgnECInstances = new();
        if (type == null)
        {
            return dgnECInstances;
        }
        DgnECManager manager = DgnECManager.Manager;
        ECQuery eCQuery = QueryHelper.CreateQuery(type.ECClass.Schema, new string[] { type.Name });
        eCQuery.SelectClause.SelectAllProperties = true;
        FindInstancesScope findInstancesScope = FindInstancesScope.CreateScope(GeneralHelpers.ActiveDgnFile, new FindInstancesScopeOption(DgnECHostType.Element, includeAttach));
        if (findInstancesScope == null)
        {
            return dgnECInstances;
        }
        using DgnECInstanceCollection dgnECInstanceCollection = manager.FindInstances(findInstancesScope, eCQuery);

        if (dgnECInstanceCollection != null)
        {
            dgnECInstances = dgnECInstanceCollection.ToList();
        }

        return dgnECInstances;
    }
    public static List<IDgnECInstance> GetECInstanceFromElement(Element element)
    {
        DgnECManager manager = DgnECManager.Manager;
        return manager.GetElementProperties(element, ECQueryProcessFlags.SearchAllClasses).ToList();
    }
    public static IDgnECInstance GetECInstanceFromElement(Element element, string itemTypeName)
    {
        foreach (IDgnECInstance item in GetECInstanceFromElement(element))
        {
            if (item.ClassDefinition.DisplayLabel == itemTypeName)
            {
                return item;
            }
        }
        return null;
    }
    public static object GetValue(IDgnECInstance instance, string propertyName)
    {
        IECClass classDefinition = instance.ClassDefinition;
        foreach (IECProperty eCProperty in classDefinition.Properties(true))
        {
            if (eCProperty.DisplayLabel == propertyName)
            {
                IECPropertyValue eCPropertyValue = instance.FindPropertyValue(eCProperty.Name, false, false, false, false);
                if (eCPropertyValue != null)
                {
                    instance.WriteChanges();
                    return eCPropertyValue.NativeValue;
                }
            }
        }
        return null;
    }
    public static bool SetValue<T>(IDgnECInstance instance, string propertyName, T value)
    {
        IECClass classDefinition = instance.ClassDefinition;
        foreach (IECProperty eCProperty in classDefinition.Properties(true))
        {
            if (eCProperty.DisplayLabel != propertyName)
            {
                continue;
            }
            IECPropertyValue eCPropertyValue = instance.FindPropertyValue(eCProperty.Name, false, false, false, false);
            if (eCPropertyValue != null && !eCPropertyValue.IsReadOnly)
            {
                instance.SetValue<T>(eCProperty.Name, value);
                return instance.WriteChanges() == StatusInt.Success;
            }
        }
        return false;
    }
    public static bool SetValues<T>(IDgnECInstance instance, string propertyName, List<T> value)
    {
        IECClass classDefinition = instance.ClassDefinition;
        foreach (IECProperty eCProperty in classDefinition.Properties(true))
        {
            if (eCProperty.DisplayLabel == propertyName)
            {
                if (instance.FindPropertyValue(eCProperty.Name, true, true, true) is IECArrayValue eCArrayValues)
                {
                    eCArrayValues.SetValues<T>(value);
                    return instance.WriteChanges() == StatusInt.Success;
                }
            }
        }
        return false;
    }
    public static bool CreatePickList(string enumName, List<string> values)
    {
        DgnFile activeFile = GeneralHelpers.ActiveDgnFile;
        if (activeFile == null)
        {
            return false;
        }
        PickListLibrary pickListLibrary = PickListLibrary.Create();
        if (pickListLibrary == null)
        {
            return false;
        }
        PickList pickList = pickListLibrary.AddPickList(enumName, activeFile);
        if (pickList == null)
        {
            return false;
        }
        foreach (string value in values)
        {
            pickList.AddValue(value);
        }
        return PickListLibrary.SavePickListLibToDgn(activeFile, pickListLibrary, false);
    }
    public static PickList GetPickListFormName(string enumName)
    {
        DgnFile activeFile = GeneralHelpers.ActiveDgnFile;
        PickListLibrary pickListLibrary = PickListLibrary.Create();
        PickListLibrary.GetPickListLibFromDgn(activeFile, pickListLibrary);
        return pickListLibrary.GetPickListByName(enumName);
    }
    public static bool DeletePickList(string enumName)
    {
        DgnFile activeFile = GeneralHelpers.ActiveDgnFile;
        if (activeFile == null)
        {
            return false;
        }
        PickListLibrary pickListLibrary = PickListLibrary.Create();
        PickListLibrary.GetPickListLibFromDgn(activeFile, pickListLibrary);
        PickList pickListByName = pickListLibrary.GetPickListByName(enumName);
        if (pickListByName == null)
        {
            return false;
        }
        return pickListLibrary.RemovePickListByName(enumName);
    }
    public static bool ProConnectPickList(CustomProperty pro, string enumName)
    {
        if (pro == null)
        {
            return false;
        }
        pro.PickListName = enumName;
        return true;
    }
    public static void AddItemType(string libraryName, string itemTypeName, List<Tuple<string, CustomProperty.TypeKind, bool, bool>> propertyTypeNames)
    {
        ItemTypeLibrary itemTypeLibrary = ItemTypeLibrary.FindByName(libraryName, GeneralHelpers.ActiveDgnFile);
        if (itemTypeLibrary == null)
        {
            itemTypeLibrary = ItemTypeLibrary.Create(libraryName, GeneralHelpers.ActiveDgnFile);
        }
        ItemType itemType = itemTypeLibrary.GetItemTypeByName(itemTypeName);
        if (itemType == null)
        {
            itemType = itemTypeLibrary.AddItemType(itemTypeName);
        }
        foreach (var item in propertyTypeNames)
        {
            CustomProperty customProperty = itemType.GetPropertyByName(item.Item1);
            if (customProperty == null)
            {
                customProperty = itemType.AddProperty(item.Item1);
                customProperty.Type = item.Item2;
                customProperty.IsArray = item.Item3;
                customProperty.IsHiddenProperty = item.Item4;
            }
        }
        itemType.Library.Write();
    }
    public static IDgnECInstance AttachItemType(ItemType item, Element el)
    {
        if (item == null || el == null || !el.IsValid)
        {
            return null;
        }
        List<IDgnECInstance> eCInstanceList = GetECInstanceFromElement(el);
        foreach (IDgnECInstance eCInstance in eCInstanceList)
        {
            if (eCInstance.ClassDefinition.DisplayLabel == item.Name)
            {
                return eCInstance;
            }
        }
        IDgnECInstance dgnECInstance = new CustomItemHost(el, true).ApplyCustomItem(item, false);
        if (dgnECInstance == null)
        {
            return dgnECInstance;
        }
        dgnECInstance.ScheduleChanges(el);
        if (el.ElementId > (long)0)
        {
            el.ReplaceInModel(el);
        }
        return dgnECInstance;
    }
    public static IDgnECInstance AttachItemTypeToModel(ItemType item, DgnModel model)
    {
        if (item == null || model == null)
        {
            return null;
        }
        List<IDgnECInstance> eCInstanceList = GetECInstanceFromDgnModel(model);
        foreach (IDgnECInstance eCInstance in eCInstanceList)
        {
            if (eCInstance.ClassDefinition.DisplayLabel == item.Name)
            {
                return eCInstance;
            }
        }
        IDgnECInstance dgnECInstance = new CustomItemHost(model).ApplyCustomItem(item, false);
        if (dgnECInstance == null)
        {
            return dgnECInstance;
        }
        dgnECInstance.WriteChanges();
        return dgnECInstance;
    }
    public static List<IDgnECInstance> GetECInstanceFromDgnModel(DgnModel model)
    {
        DgnECManager manager = DgnECManager.Manager;
        return manager.GetModelProperties(model, ECQueryProcessFlags.SearchAllClasses).ToList();
    }
    public static IDgnECInstance GetECInstanceFromDgnModel(DgnModel model, string itemTypeName)
    {
        foreach (IDgnECInstance item in GetECInstanceFromDgnModel(model))
        {
            if (item.ClassDefinition.DisplayLabel == itemTypeName)
            {
                return item;
            }
        }
        return null;
    }
    public static bool RemoveItemType(ItemType itemType, Element el)
    {
        if (el == null || !el.IsValid)
        {
            return false;
        }
        IDgnECInstance eCInstance = GetECInstanceFromElement(el, itemType.Name);
        if (eCInstance == null)
        {
            return true;
        }
        eCInstance.ScheduleDelete(el);
        el.ReplaceInModel(el);
        return true;
    }
    public static List<Tuple<string, CustomProperty.TypeKind, bool, bool>> GetECPropertyList(string ecPropertyFilePath)
    {
        List<Tuple<string, CustomProperty.TypeKind, bool, bool>> ret = new();
        TxtLoadOptions txtLoadOption = new()
        {
            Encoding = Encoding.Default//设置编码方式
        };
        Workbook workbook = new(ecPropertyFilePath, txtLoadOption)
        {
            FileFormat = FileFormatType.CSV//可在此配置Excel文件类型//配置读取文件的类型（CSV）
        };
        Worksheet worksheet = workbook.Worksheets[0];//默认第一个Sheet页
        Cells cells = worksheet.Cells;
        for (int i = 1; i < cells.Rows.Count; i++)
        {
            string propertyName = cells.Rows[i].FirstCell.Value.ToString();
            ret.Add(new Tuple<string, CustomProperty.TypeKind, bool, bool>(propertyName, CustomProperty.TypeKind.String, false, false));
        }
        return ret;
    }
    //public static List<Tuple<string, string, string>> GetCSVData(string ecPropertyFilePath)
    //{
    //    List<Tuple<string, string, string>> ret = new();
    //    TxtLoadOptions txtLoadOption = new TxtLoadOptions();
    //    txtLoadOption.Encoding = Encoding.Default;//设置编码方式
    //    Workbook workbook = new Workbook(ecPropertyFilePath, txtLoadOption);
    //    workbook.FileFormat = FileFormatType.CSV;//可在此配置Excel文件类型//配置读取文件的类型（CSV）
    //    Worksheet worksheet = workbook.Worksheets[0];//默认第一个Sheet页
    //    Cells cells = worksheet.Cells;

    //    for (int i = 1; i < cells.Rows.Count; i++)
    //    {
    //        if (null == cells.Rows[i].FirstCell.Value)
    //        {
    //            continue;
    //        }
    //        ret.Add(new Tuple<string, string, string>(
    //            cells.Rows[i][0].Value.ToString(),
    //            cells.Rows[i][1].Value?.ToString(),
    //            cells.Rows[i][2].Value?.ToString()));
    //    }
    //    return ret;
    //}
    public static List<(string propertyName, string calculationBasis, string computationalFormula)> GetCSVData(string ecPropertyFilePath)
    {
        var ret = new List<(string propertyName, string calculationBasis, string computationalFormula)>();
        TxtLoadOptions txtLoadOption = new()
        {
            Encoding = Encoding.Default//设置编码方式
        };
        Workbook workbook = new(ecPropertyFilePath, txtLoadOption)
        {
            FileFormat = FileFormatType.CSV//可在此配置Excel文件类型//配置读取文件的类型（CSV）
        };
        Worksheet worksheet = workbook.Worksheets[0];//默认第一个Sheet页
        Cells cells = worksheet.Cells;

        for (int i = 1; i < cells.Rows.Count; i++)
        {
            if (null == cells.Rows[i].FirstCell.Value)
            {
                continue;
            }
            //ret.Add(new Tuple<string, string, string>(cells.Rows[i][0].Value.ToString(), cells.Rows[i][1].Value?.ToString(),cells.Rows[i][2].Value?.ToString()));
            ret.Add((cells.Rows[i][0].Value.ToString(), cells.Rows[i][1].Value?.ToString(), cells.Rows[i][2].Value?.ToString()));
        }
        return ret;
    }
}
